package cn.isjinhao.se.structure.impl;

import cn.isjinhao.se.structure.KeySupported;
import cn.isjinhao.se.structure.StructureException;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 一个Cell对应的是数据库表中的一个单元格。
 * <p>
 * 1.当object为null时，对columnMetaInfo没有限制
 * 2.当columnMetaInfo为null时，对object没有限制
 * 3.当object和columnMetaInfo都不为null时。满足：columnMetaInfo.checkTypeMatch(object) == true。
 *
 * @Author ISJINHAO
 * @Date 2021/7/2 14:04
 */
public class Cell implements KeySupported<Cell> {

    private Tuple tuple;

    /**
     * 这种格式是可以插入到MySQL中的
     */
    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    private ColumnMetaInfo columnMetaInfo;

    private Object object;

    private Position position;

    public Cell(ColumnMetaInfo columnMetaInfo, Object object) {
        if(object == null && columnMetaInfo == null) {
            throw new IllegalArgumentException("无法使用null初始化Cell！");
        }
        if (columnMetaInfo != null && !columnMetaInfo.checkTypeMatch(object)) {
            throw new IllegalArgumentException("列的类型和数据的类型不一致！");
        }
        this.columnMetaInfo = columnMetaInfo;
        this.object = object;
    }

    public void setTuple(Tuple tuple) {
        this.tuple = tuple;
    }

    public ColumnMetaInfo getColumnMetaInfo() {
        if(tuple != null && tuple.getTableMetaInfo() != null) {
            return tuple.getTableMetaInfo().get(position.getColumnIndex());
        }
        return columnMetaInfo;
    }

    public void setColumnMetaInfo(ColumnMetaInfo columnMetaInfo) {
        if (columnMetaInfo != null && !columnMetaInfo.checkTypeMatch(this.getObject())) {
            throw new IllegalArgumentException("列的类型和数据的类型不一致！");
        }
        this.columnMetaInfo = columnMetaInfo;
    }

    public void setColumnMetaInfo(String name, Class<?> clazz) {
        ColumnMetaInfo columnMetaInfo = new ColumnMetaInfo(name, clazz);
        setColumnMetaInfo(columnMetaInfo);
    }

    public Cell(Object object) {
        this.object = object;
    }

    public Object getObject() {
        return object;
    }

    public void setObject(Object object) {
        if(columnMetaInfo == null || columnMetaInfo.checkTypeMatch(object)) {
            this.object = object;
        } else {
            throw new StructureException("接收的数据的类型(" + object.getClass().getName() + ", " + object + ")与已存在的数据类型(" + columnMetaInfo.getClazz().getName() + ")不匹配！");
        }
    }

    public String simpleToString() {
        return object.toString();
    }

    public Position getPosition() {
        return position;
    }

    public void setPosition(Position position) {
        this.position = position;
    }

    @Override
    public String toString() {
        return "Cell{" +
                "columnMetaInfo=" + columnMetaInfo +
                ", object=" + object +
                ", position=" + position +
                '}';
    }

    public String mysqlToString() {
        if (object == null) {
            return null;
        }
        if (object instanceof LocalDateTime) {
            return DATE_TIME_FORMATTER.format((LocalDateTime) object);
        }
        return object.toString();
    }

    @Override
    public Cell key() {
        return this;
    }

}